<template>
  <div class="chat-container">
    <!-- 聊天内容区域 -->
    <div class="chat-messages">
      <div
          v-for="(item, index) in messages"
          :key="index"
          :class="['message-bubble', item.isUser ? 'user-message' : 'ai-message']">
        <!-- 用户消息 -->
        <div v-if="item.isUser" class="user-content">
          {{ item.content }}
        </div>
        <!-- AI消息 -->
        <div v-else class="ai-content">
          <div v-if="item.parsed.reasoning_content && useDeepSeek" class="reasoning">
            <span class="thinking-label">思考过程：</span>
            <div v-html="dompurify.sanitize(marked(item.parsed.reasoning_content))"></div>
          </div>
          <div
              v-if="item.parsed?.content?.trim()"
              class="answer-content"
              v-html="dompurify.sanitize(marked(item.parsed.content))"
          ></div>
          <div v-else class="loading-indicator">
            <i class="el-icon-loading"></i>
            正在生成回答...
          </div>
        </div>
      </div>
    </div>

    <!--  底部控制区  -->
    <div class="bottom-controls">
      <!--   开关控制行   -->
      <div class="control-row">
        <el-switch
            v-model="useDeepSeek"
            active-text="启用深度思考"
            inactive-text="简单 Chat"
            class="mode-switch"
        />
        <!-- 新增清空按钮 -->
        <el-button
            v-if="messages.length > 0"
            type="info"
            plain
            @click="clearMessages"
            class="clear-button"
        >
          清空聊天记录
        </el-button>
      </div>
      <!--   输入框行   -->
      <div class="input-row">
        <el-input
            v-model="prompt"
            placeholder="请输入问题"
            class="chat-input"
            type="textarea"
            :autosize="{minRows:1, maxRows:4}"
            @keydown.enter.prevent="handleKeydown"
        >
        </el-input>
        <!-- 新增取消按钮 -->
        <el-button
            v-if="loading"
            type="danger"
            @click="cancelRequest"
            class="cancel-button"
            :disabled="!loading"
        >
          停止生成
        </el-button>
        <el-button
            type="primary"
            @click="startChat"
            :icon="Right"
            :loading="loading"
            class="send-button"
        />
      </div>
    </div>
  </div>
</template>

<script>import SseService from "../../services/sseService.js";
import DOMPurify from 'dompurify';
import { Right } from "@element-plus/icons-vue";
import {getToken, msgTip} from "../../util/util.js";
import {marked} from "marked";
import {doGet} from "../../http/httpRequest.js";

export default {
  name: "ChatView",
  computed: {
    Right() {
      return Right
    }
  },
  components: { Right },
  data() {
    return {
      loading: false,
      prompt: "",
      messages: [],
      sseService: null,
      isInThinkTag: false,
      useDeepSeek: true,
      dompurify: DOMPurify,
      isLogin: false,
    };
  },
  methods: {
    marked,
    handleKeydown(event) {
      if (event.ctrlKey || event.metaKey) {
        event.preventDefault();
        this.prompt += '\r\n';
      } else if (!event.shiftKey) {
        if (this.loading) {
          msgTip('请等待请求完成', 'error');
          event.preventDefault();
          return;
        }
        this.startChat();
      }
    },

    async startChat() {

      // 新增登录校验逻辑
        const token = getToken();
        if (token) {
          // 使用 await 等待请求完成
          const resp = await doGet("/system/user/autoLogin", {});
          this.isLogin = resp.data.code === 200;
        } else {
          this.isLogin = false;
        }


      if(!this.isLogin) {
        return ;
      }

      if (this.loading) {
        console.warn('请求正在进行中');
        return;
      }

      this.loading = true;

      try {
        const prompt = this.prompt.trim();
        if (!prompt) {
          msgTip('请输入有效内容', 'warning');
          return;
        }

        // 添加消息记录
        this.messages.push(
            {
              time: new Date().toLocaleTimeString(),
              content: prompt,
              isUser: true,
            },
            {
              time: new Date().toLocaleTimeString(),
              parsed: { reasoning_content: '', content: '' },
              isUser: false
            }
        );

        const endpoint = this.useDeepSeek ? '/ai/chat' : '/ai/simple-chat';
        this.sseService = new SseService(endpoint);

        // 初始化SSE连接
        this.sseService.connect(
            prompt.replace(/\r\n/g, ''),
            {
              onConnect: () => {
                this.loading = true; // 连接成功时设置loading
              },
              onData: (data) => this.handleData(data),
              onError: (error) => {
                this.loading = false;
              },
              onComplete: () => {
                this.loading = false; // 完成时重置状态
              }
            }
        );

        this.prompt = '';
      } catch (error) {
        this.loading = false;
        console.error('请求初始化失败:', error);
        msgTip('请求失败', 'error');
      }
    },

    handleData(data) {
      const parsed = this.parseSSEData(data);
      if (!parsed) return;

      const lastIndex = this.messages.length - 1;
      const lastMessage = {
        ...this.messages[lastIndex],
        parsed: {
          reasoning_content: this.messages[lastIndex].parsed?.reasoning_content || '',
          content: this.messages[lastIndex].parsed?.content || ''
        }
      };

      if (parsed.reasoning_content) {
        lastMessage.parsed.reasoning_content += parsed.reasoning_content;
      }
      if (parsed.content) {
        lastMessage.parsed.content += parsed.content;
      }

      this.messages.splice(lastIndex, 1, lastMessage);
    },

    // 保持原有parseSSEData等方法不变
    parseSSEData(data) {
      try {
        const parsed = data;

        // 检查是否直接返回了 reasoning_content
        const directReasoning = parsed.choices?.[0]?.delta?.reasoning_content;
        if (directReasoning) {
          return {
            id: parsed.id,
            created: parsed.created,
            model: parsed.model,
            reasoning_content: directReasoning,
            content: parsed.choices?.[0]?.delta?.content || ''
          };
        }

        const content = parsed.choices?.[0]?.delta?.content || '';

        // 处理 think 标签包裹的情况
        if (content.includes('<think>')) {
          this.isInThinkTag = true;
          const startIndex = content.indexOf('<think>') + '<think>'.length;
          return {
            id: parsed.id,
            created: parsed.created,
            model: parsed.model,
            reasoning_content: content.substring(startIndex),
            content: content.substring(0, content.indexOf('<think>'))
          };
        }

        if (content.includes('</think>')) {
          this.isInThinkTag = false;
          const endIndex = content.indexOf('</think>');
          return {
            id: parsed.id,
            created: parsed.created,
            model: parsed.model,
            reasoning_content: content.substring(0, endIndex),
            content: content.substring(endIndex + '</think>'.length)
          };
        }

        // 根据状态决定内容归属
        return {
          id: parsed.id,
          created: parsed.created,
          model: parsed.model,
          reasoning_content: this.isInThinkTag ? content : '',
          content: this.isInThinkTag ? '' : content
        };
      } catch (e) {
        console.error('解析JSON失败:', e);
        return null;
      }
    },

    cancelRequest() {
      if (this.sseService) {
        this.sseService.disconnect();
        this.sseService = null;
        this.loading = false;
        msgTip('已停止生成', 'warning');
      }
    },
    clearMessages() {
      this.messages = [];
      msgTip('已清空聊天记录', 'success');
    }
  },
  beforeUnmount() {
    this.sseService?.disconnect();
  }
}
</script>

<style scoped>
/*:deep(.send-button .el-icon) {
  color: white !important;
}*/

/* 多行输入优化 */
:deep(.el-textarea__inner) {
  border: 1px solid #dcdfe6 !important;  /* 恢复边框 */
  transition: border-color 0.2s;
}

/* 输入框聚焦状态 */
:deep(.el-textarea.is-focus .el-textarea__inner) {
  border-color: #409eff !important;
  box-shadow: 0 0 0 1px #409eff inset;
}

.chat-container {
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  background: #f5f5f5;
}

.message-bubble {
  max-width: 70%;
  min-width: 20%; /* 确保气泡有一定的最小宽度 */
  width: fit-content; /* 根据内容自动调整宽度 */
  margin: 10px 0;
  padding: 12px 16px;
  border-radius: 8px;
  position: relative;
}

/* 底部控制区域 */
.bottom-controls {
  background: white;
  box-shadow: 0 -2px 12px rgba(0,0,0,0.08);
  padding: 15px 20px;
  position: sticky;
  bottom: 0;
}

.control-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 15px;
}

.input-row {
  max-width: 800px;
  margin: 0 auto;
  display: flex;  /* 确保子元素水平排列 */
  align-items: center;  /* 垂直居中对齐 */
}

/* 开关样式调整 */
.mode-switch {
  --el-switch-on-color: #409EFF;
  --el-switch-off-color: #dcdfe6;
}

/* 输入框样式优化 */
.chat-input {
  border-radius: 25px 0 0 25px;  /* 左侧圆角 */
  overflow: hidden;
  transition: all 0.3s;
  flex: 1;  /* 占据剩余空间 */
}

/* 多行输入时的样式调整 */
:deep(.el-textarea).chat-input {
  border-radius: 25px;

  /* 输入框聚焦状态 */
  &.is-focus {
    box-shadow: 0 0 0 1px #409eff inset;
  }
}

/* 响应式调整 */
@media (max-width: 768px) {
  :deep(.el-textarea__inner) {
    padding: 8px 15px;
  }
}

:deep(.el-input-group__append) {
  background: #409eff;
  border: 1px solid #409eff !important;  /* 恢复按钮边框 */
  border-radius: 0 25px 25px 0 !important;
  padding: 0 20px;
  display: flex;  /* 确保子元素水平排列 */
  align-items: center;  /* 垂直居中对齐 */
}

/* 按钮悬停效果 */
:deep(.send-button:hover) {
  opacity: 0.9;
  transform: scale(1.05);
}

.user-message {
  background: #409eff;
  color: white;
  margin-left: auto;
  align-self: flex-end;
}

.ai-message {
  background: white;
  border: 1px solid #ebeef5;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
  align-self: flex-start;
}

.reasoning {
  color: #666;
  font-size: 0.9em;
  border-left: 3px solid #409eff;
  padding-left: 8px;
  margin-bottom: 8px;
}

.thinking-label {
  color: #409eff;
  font-weight: 500;
}

.answer-content {
  line-height: 1.6;
}

.answer-content :deep(h1) { font-size: 1.4em; }
.answer-content :deep(h2) { font-size: 1.3em; }
.answer-content :deep(code) {
  background: #f5f5f5;
  padding: 2px 4px;
  border-radius: 3px;
}
.answer-content :deep(pre) {
  background: #f8f8f8;
  padding: 10px;
  border-radius: 5px;
  overflow-x: auto;
}

/* 移动端适配 */
@media (max-width: 768px) {
  :deep(.el-input-group__append) {
    padding: 0 15px;
  }

  .send-button span {
    display: inline-block;
    margin-left: 5px;
  }
}
</style>
